# -*- coding: utf-8 -*-
"""
    Project name：code_potentialflow
# -------------------------------
    File name：loboda_method.py
    Created on：2025/4/12 21:30
    Author：(input)
    Description:loboda文章的整个流程操作
"""
from check_SC_process import EllipticSCTransform # 椭圆函数类
from mobius import MobiusTransformSolver
from ellipticIntegral import EllipticIntegralTransform # 椭圆积分类
import sympy as sp

def scale_coordinates(point_data, divisor):
    """
    缩放原始点坐标数组中的每个 u 坐标，并将字段重命名为 up。

    参数：
    - point_data: list[dict]，原始点坐标数据，形如 [{"label": "A", "u": -0.75}, ...]
    - divisor: 实数或复数，用于缩放每个 u 坐标

    返回：
    - list[dict]，结构如 [{"label": "A", "up": u/divisor}, ...]
    """
    return [
        {"label": point["label"], "up": point["u"] / divisor}
        for point in point_data
    ]

def compare_points(*point_sets, key_names=None):
    """
    比较多个点集中的坐标信息，按 label 对齐输出。

    参数：
    - *point_sets: 多个形如 [{"label": ..., "u": ...}, {"label": ..., "up": ...}, ...] 的列表
    - key_names: 每个点集对应的键名（如 ["原始", "缩放后"]），默认用 set1, set2, ...

    打印方式类似：
        点 A：
          原始坐标   = ...
          缩放后坐标 = ...
        ----------------------------------------
    """
    if key_names is None:
        key_names = [f"set{i+1}" for i in range(len(point_sets))]

    # 构造按 label 分类的结构
    label_map = {}
    for i, point_set in enumerate(point_sets):
        for entry in point_set:
            label = entry["label"]
            coord_value = entry.copy()
            coord_value.pop("label")
            label_map.setdefault(label, {})[key_names[i]] = list(coord_value.values())[0]

    # 打印输出
    for label in sorted(label_map.keys()):
        print(f"点 {label}：")
        for name in key_names:
            value = label_map[label].get(name, "无")
            print(f"  {name:<10} = {value}")
        print("-" * 40)

def compute_z(point_data, k, C, transformer):
    """
    输入原来的点数据，使用 Jacobi sn 变换计算变换后的 z，
    返回新的数据列表，包含 label 和变换结果 z。
    """
    z_point_data = []

    for entry in point_data:
        label = entry["label"]
        u = entry["u"]
        z = transformer.compute_jacobi_sn(k, C, u)
        z_point_data.append({
            "label": label,
            "z": z
        })

    return z_point_data

def get_control_points(z_point_data, selected_labels):
    """
    从z_point_data中选取4个标记点，并返回z的实部
    参数：
    - z_point_data: [{"label": str, "z": complex}]
    - selected_labels: ["A", "B", "C", "D"]
    返回：
    - controlled_point
    """

    # 提取指定 label 对应的 z 实部作为输入
    label_to_z = {entry['label']: entry['z'] for entry in z_point_data}
    try:
        z_vals = [sp.re(label_to_z[label]) for label in selected_labels]
    except KeyError as e:
        raise ValueError(f"未在数据中找到标签 {e}")

    return z_vals

def compute_zp(z_point_data, solver):
    """
    从z_point_data中求Mobius变换的结果（使用z的实部）。
    返回结构与原数据一致，但字段从z变为zp。

    参数：
    - z_point_data: [{"label": str, "z": complex}]
    - solver: Mobius求解实例
    """
    zp_point_data = []
    for entry in z_point_data:
        real_z = sp.re(entry['z'])  # 使用实部进行变换
        zp = solver.map_point(real_z)
        zp_point_data.append({
            "label": entry['label'],
            "zp": zp
        })

    return zp_point_data




def loboda():
    # 定义矩形尺寸
    width = 1.5
    height = 5.0
    # 原始点和复数坐标
    origin_point_data = [
        {"label": "A", "u": -0.75},
        {"label": "B", "u": -0.75 + 5.0j},
        {"label": "C", "u": -0.25 + 5.0j},
        {"label": "D", "u": 0.75 + 5.0j},
        {"label": "E", "u": 0.75 + 0.5j},
        {"label": "F", "u": 0.75},
        {"label": "J", "u": 0.25 + 5.0j}
    ]
    # SC变换参数计算 椭圆积分类（Legendre）
    SC_1 = EllipticSCTransform(width, height)
    C, k, k_prime = SC_1.solve()# k,考虑用alpha代替

    # 放缩原坐标为up
    scaled_point_data = scale_coordinates(origin_point_data, C)

    # SC变换到实轴上的坐标
    z_point_data = compute_z(origin_point_data, k, C, SC_1)

    # 选择控制点，并生成实数数组
    selected_labels = ["F", "E", "J", "C"]
    z_vals = get_control_points(z_point_data, selected_labels)
    # mobius变换到实轴上的坐标
    beta = sp.Symbol('beta', real=True)
    w_expr_list = [-1 / beta, -1, 1, 1 / beta]

    MBS = MobiusTransformSolver(z_vals, w_expr_list)
    sol, a, b, d, beta = MBS.solve()# beta也是SC变换中的k
    zp_point_data = compute_zp(z_point_data, MBS)

    # 椭圆函数类Jacobi
    JCB = EllipticIntegralTransform(beta)
    J_k, J_k_prime, J_K, J_K_prime = JCB.solve()










    # 调用对比函数
    compare_points(origin_point_data,
                   scaled_point_data,
                   z_point_data,
                   zp_point_data,
                   key_names=["原始坐标 u", "缩放后坐标 up","SC变换后坐标 z","Mobius变换后的坐标 zp"])






# 示例用法
if __name__ == "__main__":
    loboda()